package com.prawn.traceability.service;

import java.util.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.prawn.traceability.dao.ShrimpDao;
import com.prawn.traceability.dao.ShrimpManagementDao;

import com.prawn.traceability.pojo.ShrimpManagement;
import com.prawn.traceability.pojo.Pond;
import com.prawn.traceability.pojo.Shrimp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;
import util.IdWorker;

import com.prawn.traceability.dao.PondDao;


/**
 * 服务层
 *
 * @author Administrator
 */
@Service
@Transactional
public class PondService {

    @Autowired
    private PondDao pondDao;

    @Autowired
    private ShrimpDao shrimpDao;

    @Autowired
    private ShrimpService shrimpService;

    @Autowired
    private ShrimpManagementDao shrimpManagementDao;

    @Autowired
    private IdWorker idWorker;



//    /**
//     * 获取基地池塘信息，左连接虾种类
//     *
//     * @param baseId
//     * @return
//     */
//    public List<PondShrimpManagementDTO> getPonds(String baseId) {
//        pondDao
//    }

    /**
     * 获得养殖场池塘面积和池塘数量
     *
     * @param baseId
     * @return
     */
    public Map<String, Integer> getVolumeAndPondNum(String baseId) {
        Map<String, Integer> map = new HashMap<>();
        map.put("volume", pondDao.getVolumeSumByBaseId(baseId));
        map.put("pondNum", pondDao.getPondNumbersByBaseId(baseId));
        return map;
    }

    //捕捞虾
    public void catchShrimp(Pond pond, Double yield, String people, String specification) {
        //存放信息到虾苗信息表
        Shrimp shrimp = shrimpDao.findByPondIdAndFishingStatus(pond.getId(), "0");
        shrimp.setFishingStatus("1");
        shrimp.setFishingTime(pond.getCatchDate());
        shrimp.setYield(yield);
        shrimp.setRemain(yield);
        shrimp.setCreateBy(people);
        shrimp.setSpecification(specification);
        //修改池塘状态
//        pond.setDeliveryStatus("0");
        //增加虾苗产量到两个虾苗信息表
        ShrimpManagement shrimpManagement = shrimpManagementDao.findById(pond.getShrimpId()).get();
        if (shrimpManagement != null && !"".equals(shrimpManagement)) {
            Double old = shrimpManagement.getYield();
            shrimpManagement.setYield(old + yield);
            shrimpManagementDao.save(shrimpManagement);
        }

        pondDao.pondCatch("0", pond.getCatchDate(), pond.getId());
        shrimpService.update(shrimp);
    }

    //池塘投放虾苗，并将虾苗信息存放到虾苗信息表
    public void dropShrimp(Pond pond) {
        ShrimpManagement shrimpManagement = shrimpManagementDao.findById(pond.getShrimpId()).get();
        Shrimp shrimp = new Shrimp();
        shrimp.setShrimpBatchName(shrimpManagement.getShrimpBatchName());
        shrimp.setShrimpSpecies(shrimpManagement.getShrimpSpecies());
        shrimp.setShrimpOrigin(shrimpManagement.getShrimpOrigin());
        shrimp.setShrimpSupplier(shrimpManagement.getShrimpSupplier());
        shrimp.setPondId(pond.getId());
        shrimp.setFishingStatus("0");
        shrimp.setSeedlingTime(pond.getCreateDate());
        shrimp.setBaseId(pond.getBaseId());
        shrimp.setInputNum(pond.getInputNum());
//        pond.setDeliveryStatus("1");
        //更改虾苗剩余数量
        shrimpManagement.setRemainNumber(shrimpManagement.getRemainNumber() - pond.getInputNum());
        pondDao.drop(pond.getShrimpId(), pond.getInputNum(), pond.getCreateDate(), "1", pond.getSpecies(),pond.getId());
        shrimpService.add(shrimp);
        shrimpManagementDao.save(shrimpManagement);
    }

    /**
     * 查询全部列表
     *
     * @return
     */
    public List<Pond> findAll() {
        return pondDao.findAll();
    }


    /**
     * 条件查询+分页
     *
     * @param whereMap
     * @param page
     * @param size
     * @return
     */
    public Page<Pond> findSearch(Map whereMap, int page, int size) {
        Specification<Pond> specification = createSpecification(whereMap);
        PageRequest pageRequest = PageRequest.of(page - 1, size);
        return pondDao.findAll(specification, pageRequest);
    }


    /**
     * 条件查询
     *
     * @param whereMap
     * @return
     */
    public List<Pond> findSearch(Map whereMap) {
        Specification<Pond> specification = createSpecification(whereMap);
        return pondDao.findAll(specification);
    }

    /**
     * 根据ID查询实体
     *
     * @param id
     * @return
     */
    public Pond findById(String id) {
        return pondDao.findById(id).get();
    }

    /**
     * 增加
     *
     * @param pond
     */
    public void add(Pond pond) {
        pond.setId(idWorker.nextId() + "");
        pond.setDeliveryStatus("0");
        pondDao.save(pond);
    }

    /**
     * 修改
     *
     * @param pond
     */
    public void update(Pond pond) {
        if ("1".equals(pond.getDeliveryStatus())) {
            Pond oldPond = pondDao.findById(pond.getId()).get();
            //若修改投放的虾苗，需同步修改虾苗信息表
            if (pond.getShrimpId() != oldPond.getShrimpId() || !pond.getInputNum().equals(oldPond.getInputNum())) {
                Shrimp shrimp = shrimpDao.findByPondIdAndFishingStatus(pond.getId(), "0");
                ShrimpManagement shrimpManagement = shrimpManagementDao.findById(pond.getShrimpId()).get();

                shrimp.setShrimpBatchName(shrimpManagement.getShrimpBatchName());
                shrimp.setShrimpSpecies(shrimpManagement.getShrimpSpecies());
                shrimp.setShrimpOrigin(shrimpManagement.getShrimpOrigin());
                shrimp.setShrimpSupplier(shrimpManagement.getShrimpSupplier());
                shrimp.setInputNum(pond.getInputNum());

                shrimpManagement.setRemainNumber(shrimpManagement.getRemainNumber() + oldPond.getInputNum() - pond.getInputNum());

                shrimpManagementDao.save(shrimpManagement);
                shrimpService.update(shrimp);
            }
        }
        pondDao.save(pond);
    }

    /**
     * 删除
     *
     * @param id
     */
    public void deleteById(String id) {
        pondDao.deleteById(id);
    }

    /**
     * 动态条件构建
     *
     * @param searchMap
     * @return
     */
    private Specification<Pond> createSpecification(Map searchMap) {

        return new Specification<Pond>() {

            @Override
            public Predicate toPredicate(Root<Pond> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicateList = new ArrayList<Predicate>();
                // 池塘编号
                if (searchMap.get("id") != null && !"".equals(searchMap.get("id"))) {
                    predicateList.add(cb.like(root.get("id").as(String.class), "%" + (String) searchMap.get("id") + "%"));
                }
                // 池塘名称
                if (searchMap.get("pondName") != null && !"".equals(searchMap.get("pondName"))) {
                    predicateList.add(cb.like(root.get("pondName").as(String.class), "%" + (String) searchMap.get("pondName") + "%"));
                }
                // 基地编号
                if (searchMap.get("baseId") != null && !"".equals(searchMap.get("baseId"))) {
                    predicateList.add(cb.like(root.get("baseId").as(String.class), "%" + (String) searchMap.get("baseId") + "%"));
                }
                // 虾苗编号
                if (searchMap.get("shrimpId") != null && !"".equals(searchMap.get("shrimpId"))) {
                    predicateList.add(cb.like(root.get("shrimpId").as(String.class), "%" + (String) searchMap.get("shrimpId") + "%"));
                }
                // 创建者
                if (searchMap.get("createBy") != null && !"".equals(searchMap.get("createBy"))) {
                    predicateList.add(cb.like(root.get("createBy").as(String.class), "%" + (String) searchMap.get("createBy") + "%"));
                }
                // 投放状态
                if (searchMap.get("deliveryStatus") != null && !"".equals(searchMap.get("deliveryStatus"))) {
                    predicateList.add(cb.like(root.get("deliveryStatus").as(String.class), "%" + (String) searchMap.get("deliveryStatus") + "%"));
                }
                // 池塘类型
                if (searchMap.get("pondType") != null && !"".equals(searchMap.get("pondType"))) {
                    predicateList.add(cb.like(root.get("pondType").as(String.class), "%" + (String) searchMap.get("pondType") + "%"));
                }
                // 虾种类
                if (searchMap.get("species") != null && !"".equals(searchMap.get("species"))) {
                    predicateList.add(cb.like(root.get("species").as(String.class), "%" + (String) searchMap.get("species") + "%"));
                }

                return cb.and(predicateList.toArray(new Predicate[predicateList.size()]));

            }
        };

    }

}
